package com.hou.zookeeper;

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

public class Test01 {
    //地址
    static final String ADDR = "192.168.171.128:2181,192.168.171.129:2181,192.168.171.130:2181";
    //session超时时间
    static final int SESSION_OUTTIME = 2000;//ms
    /**
     * 信号量，阻塞程序执行，用于等待zookeeper连接(异步的)成功，发送成功信号
     */
    static final CountDownLatch connectedSemaphore = new CountDownLatch(1);

    public static void main(String[] args) throws Exception {
        //创建zk客户端(异步连接)   Watcher:监听连接
        ZooKeeper zooKeeper = new ZooKeeper(ADDR, SESSION_OUTTIME, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState keeperState = watchedEvent.getState();
                Event.EventType eventType = watchedEvent.getType();
                //如果是建立连接
                if (Event.KeeperState.SyncConnected == keeperState) {
                    if (Event.EventType.None == eventType) {
                        //如果建立连接成功，则发送信号量，让后续阻塞程序向下执行
                        connectedSemaphore.countDown();
                        System.out.println("zk 建立连接");
                    }
                }
            }
        });
        //进行阻塞,等待zk连接成功
        connectedSemaphore.await();
        //连接成功执行操作:
        //同步     路径(不允许递归创建), 数据  权限, 类型(PERSISTENT:持久) :临时节点只是一次session有效,用来实现分布式锁
        String name = zooKeeper.create("/testRoot", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        String name1 = zooKeeper.create("/testRoot/child02", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //异步   回调函数   , 回调的参数
        zooKeeper.create("/testRoot/child01", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,
                new AsyncCallback.StringCallback() {
                    @Override   //服务端响应吗: 0 成功   传入的path   参数  实际创建的path
                    public void processResult(int i, String s, Object o, String s1) {
                        System.out.println(i + " " + s + " " + o.toString() + " " + s1);
                    }
                }, "param");
        //删除 (路径必须是叶子节点,即没有下一级节点,不支持递归)
        //zooKeeper.delete("/testRoot/child01", -1);//版本号:-1表示删除所有的,像git一样,修改一次版本号加一,可删除指定版本号
        //同样支持异步,和创建一样传入回调
        //判断节点是否存在
        System.out.println(zooKeeper.exists("/testRoot/child01", false));//也可传入watch,异步回调等
        //获取
        byte[] data = zooKeeper.getData("/testRoot", false, null);
        System.out.println(new String(data));
        System.out.println(zooKeeper.getChildren("/testRoot", false));
        //修改
        zooKeeper.setData("/testRoot", "modify data root".getBytes(), -1);
        byte[] data1 = zooKeeper.getData("/testRoot", false, null);
        System.out.println(new String(data1));


        Thread.sleep(3000);//休眠防止异步
        zooKeeper.close();//释放资源
    }
}
